package com.cjr.ddp.util;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author cjr
 * @date Created in 2020-03-05 21:44
 * @description
 * @modified By
 */
public class MyTools {
    // 获取一个六位数的随机验证码
    public static String getCode() {
        String sms = "";
        int[] nums = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
        int count = 0;
        for (int i = 0; i < nums.length; i++) {
            sms += new Random().nextInt(nums.length);
            count++;
            if (count == 6) {
                break;
            }
        }
        return sms;
    }

    // 判断对象里的某个属性是否存在空值
    public static Set<String> isAllFieldNull(Object obj) throws Exception {
        Set<String> set = new HashSet<String>();
        Class stuCla = (Class) obj.getClass();// 得到类对象
        Field[] fs = stuCla.getDeclaredFields();// 得到属性集合
        for (Field f : fs) {// 遍历属性
            f.setAccessible(true); // 设置属性是可以访问的(私有的也可以)
            Object val = f.get(obj);// 得到此属性的值
            if (val == null) {// 只要有1个属性不为空,那么就不是所有的属性值都为空
                set.add(f.getName());
            }
        }
        return set;
    }

    // 判断对象是否为空
    public static boolean isEmpty(Object obj) {
        if (obj == null) {
            return true;
        }
        if ((obj instanceof List)) {
            return ((List) obj).size() == 0;
        }
        if ((obj instanceof String)) {
            return ((String) obj).trim().equals("");
        }
        return false;
    }

    // 获取请求者IP地址
    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    public static boolean updateNotNullField(Object rawObject, Object newObject)
            throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
        // 如果连个对象不一致。不进行更新字段值的操作
        if (rawObject.getClass().getName() != newObject.getClass().getName()) {
            return false;
        }
        // 获取原始对象中的所有public方法
        Method[] methods = rawObject.getClass().getDeclaredMethods();
        // 用于提取不包含指定关键词的方法
        String regExpression = "^(get)(?!Id|patientCount|appointmentTime)(\\w+)";
        Pattern pattern = Pattern.compile(regExpression);
        Matcher m;
        for (Method method : methods) {
            m = pattern.matcher(method.getName());
            // 正则匹配以get开头，后面不能匹配Id、CreateTime这两个单词的方法
            if (m.find()) {
                Object o = method.invoke(newObject, null);
                // 忽略值为空的字段
                if (o == null) {
                    continue;
                }
                // 取出get方法名后面的字段名
                String fieldName = m.group(2);
                // 找到该字段名的set方法
                Method rawMethod = rawObject.getClass().getMethod("set" + fieldName, method.getReturnType());
                // 调用实体对象的set方法更新字段值
                rawMethod.invoke(rawObject, o);
            }
        }
        return true;
    }

    public static boolean updateNotNullFieldForPatient(Object rawObject, Object newObject)
            throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
        // 如果连个对象不一致。不进行更新字段值的操作
        if (rawObject.getClass().getName() != newObject.getClass().getName()) {
            return false;
        }
        // 获取原始对象中的所有public方法
        Method[] methods = rawObject.getClass().getDeclaredMethods();
        // 用于提取不包含指定关键词的方法
        String regExpression = "^(get)(?!Id)(\\w+)";
        Pattern pattern = Pattern.compile(regExpression);
        Matcher m;
        for (Method method : methods) {
            m = pattern.matcher(method.getName());
            // 正则匹配以get开头，后面不能匹配Id、CreateTime这两个单词的方法
            if (m.find()) {
                Object o = method.invoke(newObject, null);
                // 忽略值为空的字段
                if (o == null) {
                    continue;
                }
                if ("".equals(o)) {
                    continue;
                }
                // 取出get方法名后面的字段名
                String fieldName = m.group(2);
                // 找到该字段名的set方法
                Method rawMethod = rawObject.getClass().getMethod("set" + fieldName, method.getReturnType());
                // 调用实体对象的set方法更新字段值
                rawMethod.invoke(rawObject, o);
            }
        }
        return true;
    }

    // 判断是否为图片
    public static Boolean isImageFile(String filesName) {
        String[] img_type = new String[]{".jpg", ".jpeg", ".png", ".gif", ".bmp"};
        if (filesName == null) {
            return false;
        }
        filesName = filesName.toLowerCase();
        for (String type : img_type) {
            if (filesName.endsWith(type)) {
                return true;
            }
        }
        return false;
    }

    // 获取文件后缀名
    public static String getFileType(String fileName) {
        if (fileName != null && fileName.indexOf(".") >= 0) {
            return fileName.substring(fileName.lastIndexOf("."), fileName.length()).toLowerCase();
        }
        return "";
    }

    // 获取文件名
    public static String getFileName(String fileName) {
        if (fileName != null && fileName.indexOf(".") >= 0) {
            return fileName.substring(0, fileName.lastIndexOf(".")).toLowerCase();
        }
        return "";
    }

    /*
     * 将时间转换为时间戳
     */
    public static String dateToStamp(String s) throws ParseException {
        String res;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        java.util.Date date = simpleDateFormat.parse(s);
        long ts = date.getTime();
        res = String.valueOf(ts);
        return res;
    }

    /*
     * 将时间戳转换为时间
     */
    public static Date stampToDate(String s) {
        long lt = new Long(s);
        Date date = new Date(lt);
        return date;
    }

    /**
     * 判断是否为真实手机号
     *
     * @param mobiles
     * @return
     */
    public static boolean isMobile(String mobiles) {
        Pattern p = Pattern.compile("/^1[345678]\\d{9}$/");
        Matcher m = p.matcher(mobiles);
        return m.matches();
    }

    public static List<java.util.Date> dateToWeek(java.util.Date mdate) {
        int b = mdate.getDay();
        java.util.Date fdate;
        List<java.util.Date> list = new ArrayList();
        Long fTime = mdate.getTime() - b * 24 * 3600000;
        for (int a = 0; a < 7; a++) {
            fdate = new java.util.Date();
            fdate.setTime(fTime + (a * 24 * 3600000));
            list.add(a, fdate);
        }

        return list;
    }

    public static List<java.util.Date> getDateAfter(java.util.Date d) {
        List<java.util.Date> list = new ArrayList<java.util.Date>();
        for (int i = 1; i <= 7; i++) {
            Calendar now = Calendar.getInstance();
            now.setTime(d);
            now.set(Calendar.DATE, now.get(Calendar.DATE) + i);
            list.add(now.getTime());
        }
        return list;
    }

    public static void main(String[] args) {
        System.out.println(MyTools.getSerialNo());
    }


    public static String getSerialNo() {
        String sixChar = "";
        SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss");
        java.util.Date date = new java.util.Date();
        String time = sdf.format(date);
        for (int i = 0; i < time.length() / 2; i++) {
            String singleChar;
            String x = time.substring(i * 2, (i + 1) * 2);
            int b = Integer.parseInt(x);
            if (b < 10) {
                singleChar = Integer.toHexString(Integer.parseInt(x));
            } else if (b >= 10 && b < 36) {
                singleChar = String.valueOf((char) (Integer.parseInt(x) + 55));
            } else {
                singleChar = String.valueOf((char) (Integer.parseInt(x) + 61));
            }
            sixChar = sixChar + singleChar;

        }
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        return StringUtils.split(df.format(new java.util.Date()), " ")[0].replace("-", "") + StringUtils.split(df.format(new java.util.Date()), " ")[1].replace(":", "") + sixChar;
    }

    //获取唯一的UUID
    public static String getUUID() {
        String id = UUID.randomUUID().toString();
        //整理数据格式
        String uId = id.replaceAll("-", "");
        return uId;
    }

    /**
     * 将JSON字符串转换成对应的类
     *
     * @param objInfo
     * @param obj
     * @return
     * @throws Exception
     */
    public static Object jsonToObjectMapper(String objInfo, Object obj) throws Exception {
        ObjectMapper jm = new ObjectMapper();
        jm.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
        try {
            obj = jm.readValue(objInfo, obj.getClass());
        } catch (JsonParseException e) {
            e.printStackTrace();
            throw e;
        } catch (JsonMappingException e) {
            e.printStackTrace();
            throw e;
        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        }

        return obj;
    }

    // 四舍五入保留两位小数
    public static Double round(double num) {
        BigDecimal bg = new BigDecimal(num).setScale(2, BigDecimal.ROUND_HALF_UP);
        return bg.doubleValue();
    }

    // 根据传入的时间字符串获取对应的年份
    public static Integer getYear(String dateStr) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        java.util.Date date = null;
        int year = 0;
        try {
            date = sdf.parse(dateStr);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            year = calendar.get(Calendar.YEAR);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return year;
    }

    // 根据传入的时间字符串获取对应的月份
    public static Integer getMonth(String dateStr) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        java.util.Date date = null;
        int month = 0;
        try {
            date = sdf.parse(dateStr);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            month = calendar.get(Calendar.MONTH) + 1;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return month;
    }

    // 根据传入的时间字符串获取对应的上一年的年月 时间字符串格式为(2019-08)
    public static String getPreviousYearMonth(String dateStr) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        java.util.Date date = null;
        int year = 0;
        String month = "";
        try {
            date = sdf.parse(dateStr);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            year = calendar.get(Calendar.YEAR) - 1;
            month = (calendar.get(Calendar.MONTH) + 1) < 10 ? "0" + (calendar.get(Calendar.MONTH) + 1) : (calendar.get(Calendar.MONTH) + 1) + "";
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return year + "-" + month;
    }

    // 根据传入的时间字符串获取对应的上一月的年月 时间字符串格式为(2019-08)
    public static String getPreviousMonth(String dateStr) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        java.util.Date date = null;
        int year = 0;
        String month = "";
        try {
            date = sdf.parse(dateStr);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            year = calendar.get(Calendar.YEAR);
            month = (calendar.get(Calendar.MONTH)) < 10 ? "0" + (calendar.get(Calendar.MONTH) + 1) : (calendar.get(Calendar.MONTH) + 1) + "";
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return year + "-" + month;
    }

    //把参数替换成当前输入的时间
    public static String replaceStr(String where, String startDate, String endDate, String departmentId) {
//        String param = where.substring(where.indexOf(":") + 1, where.lastIndexOf(":"));
        where = where.replace(":startDate:", "'" + startDate + "'");
        where = where.replace(":endDate:", "'" + endDate + "'");
        where = where.replace(":departmentId:", departmentId + "");
//        if ("startDate".equals(param)) {
//            where = where.replace(":startDate:", "'" + startDate + "'");
//        }
//        if ("endDate".equals(param)) {
//            where = where.replace(":endDate:", "'" + endDate + "'");
//        }
//        if ("departmentId".equals(param)) {
//            where = where.replace(":departmentId:", departmentId + "");
//        }
        return where;
    }

    //把参数替换成当前输入时间的前一年的时间
    public static String replaceStrUpYear(String where, String startDate, String endDate, String departmentId) {
//        String param = where.substring(where.indexOf(":") + 1, where.lastIndexOf(":"));
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        Calendar end = Calendar.getInstance();
        try {
            c.setTime(simpleDateFormat.parse(startDate));
            c.add(Calendar.YEAR, -1);
            startDate = simpleDateFormat.format(c.getTime());
            end.setTime(simpleDateFormat.parse(endDate));
            end.add(Calendar.YEAR, -1);
            endDate = simpleDateFormat.format(end.getTime());
            where = where.replace(":startDate:", "'" + startDate + "'");
            where = where.replace(":endDate:", "'" + endDate + "'");
            where = where.replace(":departmentId:", departmentId + "");


//            if ("startDate".equals(param)) {
//                where = where.replace(":startDate:", "'" + startDate + "'");
//            }
//            if ("endDate".equals(param)) {
//                where = where.replace(":endDate:", "'" + endDate + "'");
//            }
//            if ("departmentId".equals(param)) {
//                where = where.replace(":departmentId:", departmentId + "");
//            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return where;
    }

    //把参数替换成当前输入时间的前一个月的时间
    public static String replaceStrUpMonth(String where, String startDate, String endDate, String departmentId) {
//        String param = where.substring(where.indexOf(":") + 1, where.lastIndexOf(":"));
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        Calendar end = Calendar.getInstance();
        try {
            c.setTime(simpleDateFormat.parse(startDate));
            c.add(Calendar.MONTH, -1);
            startDate = simpleDateFormat.format(c.getTime());
            end.setTime(simpleDateFormat.parse(endDate));
            end.add(Calendar.MONTH, -1);
            endDate = simpleDateFormat.format(end.getTime());
            where = where.replace(":startDate:", "'" + startDate + "'");
            where = where.replace(":endDate:", "'" + endDate + "'");
            where = where.replace(":departmentId:", departmentId + "");


//            if ("startDate".equals(param)) {
//                where = where.replace(":startDate:", "'" + startDate + "'");
//            }
//            if ("endDate".equals(param)) {
//                where = where.replace(":endDate:", "'" + endDate + "'");
//            }
//            if ("departmentId".equals(param)) {
//                where = where.replace(":departmentId:", departmentId + "");
//            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return where;
    }

    /**
     * 获得该月最后一天
     *
     * @param year
     * @param month
     * @return
     */
    public static String getLastDayOfMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        //设置年份
        cal.set(Calendar.YEAR, year);
        // 设置月份
        cal.set(Calendar.MONTH, month - 1);
        // 获取某月最大天数
        int lastDay = 0;
        //2月的平年瑞年天数
        if (month == 2) {
            lastDay = cal.getLeastMaximum(Calendar.DAY_OF_MONTH);
        } else {
            lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        }
        // 设置日历中月份的最大天数
        cal.set(Calendar.DAY_OF_MONTH, lastDay);
        // 格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String lastDayOfMonth = sdf.format(cal.getTime());
        return lastDayOfMonth;
    }

    /**
     * 根据年 月获取当月的每一天
     *
     * @param year
     * @param month
     * @return
     */
    public static List<String> getDayByMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        //设置年份
        cal.set(Calendar.YEAR, year);
        // 设置月份
        cal.set(Calendar.MONTH, month - 1);
        // 获取某月最大天数
        int lastDay = 0;
        //2月的平年瑞年天数
        if (month == 2) {
            lastDay = cal.getLeastMaximum(Calendar.DAY_OF_MONTH);
        } else {
            lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        }
        // 设置日历中月份的最大天数
        cal.set(Calendar.DAY_OF_MONTH, lastDay);
        int day = cal.getActualMaximum(Calendar.DATE);
        List list = new ArrayList();
        for (int i = 1; i <= day; i++) {
            String aDate = null;
            if (month < 10 && i < 10) {
                aDate = String.valueOf(year) + "-0" + month + "-0" + i;
            }
            if (month < 10 && i >= 10) {
                aDate = String.valueOf(year) + "-0" + month + "-" + i;
            }
            if (month >= 10 && i < 10) {
                aDate = String.valueOf(year) + "-" + month + "-0" + i;
            }
            if (month >= 10 && i >= 10) {
                aDate = String.valueOf(year) + "-" + month + "-" + i;
            }

            list.add(aDate);
        }
        return list;
    }


    /**
     * @param big
     * @param small
     * @return int   获取字符串个数
     * @throws
     * @author cjr
     * @date 2019/10/25 9:29
     */
    public static int getCount(String big, String small) {

        int count = 0;//出现小串的次数
        int index = -1;//出现小串的位置
        //indexof没有找到字符串则会返回-1，否则的话就是找见了
        while ((index = big.indexOf(small)) != -1) {
            count++;
            //截取调index+1之前的字符串，然后重新进行循环
            big = big.substring(index + 1);
        }
        return count;

    }

}
